package com.example.point

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationVector1D
import androidx.compose.animation.core.AnimationVector2D
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt
import kotlin.random.Random

// 动画持续时间(毫秒)
private const val SCALE_ANIMATION_DURATION = 300
private const val MOVE_ANIMATION_DURATION = 500
private const val INERTIA_ANIMATION_DURATION = 500L

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            // 调用切换页面的函数
            NetworkAnimationToggleScreen()
        }
    }
}

data class AnimationPattern(
    val linearSpeed: Float,
    val radiusAmp: Float,
    val radiusSpeed: Float,
    val sizeAmp: Float,
    val sizeSpeed: Float,
    val rotate3DSpeed: Float
)

data class Point(
    val id: Int,
    val baseX: Float,
    val baseY: Float,
    val baseRadius: Float = 8f,
    val color: Color = Color.White,
    val orbitRadius: Float = 80f,
    val animationMode: Int = 0
)

data class Connection(
    val fromPointId: Int,
    val toPointId: Int,
    val strokeWidth: Float = 2f,
    val color: Color = Color.Gray
)

@Composable
fun NetworkAnimationScreen() {
    // 原有的动画和绘制代码
    val animationPatterns = remember {
        listOf(
            AnimationPattern(20f, 30f, 0.6f, 4f, 1.0f, 2.5f),
            AnimationPattern(50f, 20f, 0.8f, 3f, 1.2f, 1.8f),
            AnimationPattern(30f, 40f, 0.4f, 5f, 0.8f, 3.0f),
            AnimationPattern(40f, 25f, 1.0f, 2f, 1.5f, 2.2f)
        )
    }

    val points = remember {
        listOf(
            Point(0, 200f, 100f, 20f, Color(0xFF4285F4), 60f, 0),
            Point(1, 500f, 200f, 16f, Color(0xFFEA4335), 100f, 1),
            Point(2, 150f, 600f, 24f, Color(0xFFFBBC05), 80f, 2),
            Point(3, 400f, 400f, 18f, Color(0xFF34A853), 120f, 3),
            Point(4, 250f, 500f, 22f, Color(0xFF5E35B1), 70f, 0),
            Point(5, 700f, 450f, 20f, Color(0xFFFF9800), 90f, 1),
            Point(6, 800f, 900f, 18f, Color(0xFF03A9F4), 110f, 2)
        )
    }

    val connections = remember {
        listOf(
            Connection(0, 1), Connection(0, 2), Connection(1, 3),
            Connection(1, 5), Connection(2, 4), Connection(3, 4),
            Connection(4, 6)
        )
    }

    val pointOffsets = remember { mutableStateMapOf<Int, Offset>() }
    val pointAngles = remember { mutableStateMapOf<Int, Float>() }
    val point3DAngles = remember { mutableStateMapOf<Int, Float>() }
    val dynamicRadii = remember { mutableStateMapOf<Int, Float>() }
    val dynamicSizes = remember { mutableStateMapOf<Int, Float>() }
    val speedMultipliers = remember { mutableStateMapOf<Int, Float>() }

    // 状态管理
    val clickedPointId = remember { mutableStateOf<Int?>(null) }
    val pointScaleAnimations = remember {
        mutableStateMapOf<Int, Animatable<Float, AnimationVector1D>>()
    }
    val pointPositionAnimations = remember {
        mutableStateMapOf<Int, Animatable<Offset, AnimationVector2D>>()
    }
    val screenCenter = remember { mutableStateOf(Offset.Zero) }
    val coroutineScope = rememberCoroutineScope()

    // 缩放和拖动状态
    val scale = remember { mutableStateOf(1f) }
    val offset = remember { mutableStateOf(Offset.Zero) }

    // 动画缩放和拖动
    val animatedScale = remember { Animatable(1f) }
    val animatedOffset = remember { Animatable(Offset.Zero, Offset.VectorConverter) }

    // 初始化所有点的动画状态
    LaunchedEffect(Unit) {
        points.forEach { point ->
            pointScaleAnimations[point.id] = Animatable(1f)
            pointPositionAnimations[point.id] = Animatable(Offset(point.baseX, point.baseY), Offset.VectorConverter)
        }
    }

    LaunchedEffect(Unit) {
        points.forEach { point ->
            pointAngles[point.id] = Random.nextFloat() * 360f
            point3DAngles[point.id] = 0f
            dynamicRadii[point.id] = point.orbitRadius
            dynamicSizes[point.id] = point.baseRadius
            pointOffsets[point.id] = Offset.Zero
            speedMultipliers[point.id] = 1.0f
        }

        val phaseOffsets = points.associate { it.id to Random.nextFloat() * 2f * PI.toFloat() }
        val frequencyFactors = points.associate { it.id to 0.1f + Random.nextFloat() * 0.2f }
        var elapsedTime = 0f
        val frameTime = 16f / 1000f

        while (true) {
            elapsedTime += frameTime

            points.forEach { point ->
                val phase = phaseOffsets[point.id] ?: 0f
                val frequency = frequencyFactors[point.id] ?: 0.15f
                speedMultipliers[point.id] = 1.15f + 0.35f * sin(elapsedTime * frequency + phase)

                val pattern = animationPatterns[point.animationMode % 4]
                val currentMultiplier = speedMultipliers[point.id] ?: 1.0f

                dynamicRadii[point.id] = point.orbitRadius +
                        pattern.radiusAmp * sin(elapsedTime * pattern.radiusSpeed)

                dynamicSizes[point.id] = point.baseRadius +
                        pattern.sizeAmp * sin(elapsedTime * pattern.sizeSpeed)

                val currentRadius = dynamicRadii[point.id]!!
                if (currentRadius > 0) {
                    val angularSpeedRad = pattern.linearSpeed / currentRadius * currentMultiplier
                    pointAngles[point.id] = (pointAngles[point.id]!! + angularSpeedRad * frameTime) % 360f
                }

                point3DAngles[point.id] = (point3DAngles[point.id]!! +
                        pattern.rotate3DSpeed * currentMultiplier * frameTime) % 360f

                val radian = Math.toRadians(pointAngles[point.id]!!.toDouble())
                val baseOffset = Offset(
                    (currentRadius * cos(radian)).toFloat(),
                    (currentRadius * sin(radian)).toFloat()
                )

                val rotateRadian = Math.toRadians(point3DAngles[point.id]!!.toDouble())
                pointOffsets[point.id] = Offset(
                    (baseOffset.x * cos(rotateRadian) - baseOffset.y * sin(rotateRadian)).toFloat(),
                    (baseOffset.x * sin(rotateRadian) + baseOffset.y * cos(rotateRadian)).toFloat()
                )
            }
            delay(16)
        }
    }

    // 双指缩放和拖动处理，以及点击事件处理
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFF121212))
            .pointerInput(Unit) {
                detectTransformGestures { centroid, pan, zoom, rotation ->
                    val newScale = scale.value * zoom
                    scale.value = newScale.coerceIn(0.5f, 5f)

                    val newOffset = offset.value + pan
                    offset.value = newOffset
                }
            }
            .pointerInput(Unit) {
                detectTapGestures { tapOffset ->
                    // 获取屏幕中心
                    val centerX = size.width / 2f
                    val centerY = size.height / 2f
                    screenCenter.value = Offset(centerX, centerY)

                    points.forEach { point ->
                        val currentPosition = pointPositionAnimations[point.id]?.value ?: Offset(point.baseX, point.baseY)
                        val center = (currentPosition + (pointOffsets[point.id] ?: Offset.Zero)) * scale.value + offset.value
                        val currentSize = dynamicSizes[point.id] ?: point.baseRadius
                        val distance = sqrt(
                            (tapOffset.x - center.x) * (tapOffset.x - center.x) +
                                    (tapOffset.y - center.y) * (tapOffset.y - center.y)
                        )

                        if (distance <= currentSize * 2f * scale.value) {
                            coroutineScope.launch {
                                val previousId = clickedPointId.value
                                val isSamePointClicked = clickedPointId.value == point.id
                                clickedPointId.value = if (isSamePointClicked) null else point.id

                                // 同时启动缩小和放大动画
                                val previousJob = previousId?.let { id ->
                                    launch {
                                        pointScaleAnimations[id]?.animateTo(
                                            1f,
                                            animationSpec = tween(SCALE_ANIMATION_DURATION)
                                        )
                                    }
                                }

                                val currentJob = if (clickedPointId.value != null) {
                                    launch {
                                        pointScaleAnimations[point.id]?.animateTo(
                                            2f,
                                            animationSpec = tween(SCALE_ANIMATION_DURATION)
                                        )
                                    }
                                } else null

                                // 处理移动动画
                                if (clickedPointId.value != null && !isSamePointClicked) {
                                    // 计算所有点的新位置
                                    val targetPositions = mutableMapOf<Int, Offset>()
                                    points.forEach { p ->
                                        val currentPos = pointPositionAnimations[p.id]?.value ?: Offset(p.baseX, p.baseY)
                                        if (p.id == point.id) {
                                            // 被点击的点移动80%到中心
                                            val direction = (screenCenter.value - offset.value) / scale.value - currentPos
                                            targetPositions[p.id] = currentPos + direction * 0.8f
                                        } else {
                                            // 其他点保持相对位置移动
                                            val clickedOriginalPos = Offset(point.baseX, point.baseY)
                                            val otherOriginalPos = Offset(p.baseX, p.baseY)
                                            val originalOffset = otherOriginalPos - clickedOriginalPos
                                            val clickedNewPos = currentPos + ((screenCenter.value - offset.value) / scale.value - currentPos) * 0.8f
                                            targetPositions[p.id] = clickedNewPos + originalOffset
                                        }
                                    }

                                    // 启动所有点的移动动画
                                    val moveJobs = points.map { p ->
                                        launch {
                                            pointPositionAnimations[p.id]?.animateTo(
                                                targetPositions[p.id]!!,
                                                animationSpec = tween(MOVE_ANIMATION_DURATION)
                                            )
                                        }
                                    }
                                    moveJobs.joinAll()
                                } else if (clickedPointId.value == null) {
                                    // 返回原始位置
                                    val returnJobs = points.map { p ->
                                        launch {
                                            pointPositionAnimations[p.id]?.animateTo(
                                                Offset(p.baseX, p.baseY),
                                                animationSpec = tween(MOVE_ANIMATION_DURATION)
                                            )
                                        }
                                    }
                                    returnJobs.joinAll()
                                }

                                // 等待所有动画都完成
                                listOfNotNull(previousJob, currentJob).joinAll()
                            }
                            return@detectTapGestures
                        }
                    }

                    // 点击空白处取消选中
                    if (clickedPointId.value != null) {
                        val pointIdToReset = clickedPointId.value!!
                        clickedPointId.value = null
                        coroutineScope.launch {
                            val scaleJob = launch {
                                pointScaleAnimations[pointIdToReset]?.animateTo(
                                    1f,
                                    animationSpec = tween(SCALE_ANIMATION_DURATION)
                                )
                            }
                            val returnJobs = points.map { p ->
                                launch {
                                    pointPositionAnimations[p.id]?.animateTo(
                                        Offset(p.baseX, p.baseY),
                                        animationSpec = tween(MOVE_ANIMATION_DURATION)
                                    )
                                }
                            }
                            listOf(scaleJob) + returnJobs.joinAll()
                        }
                    }
                }
            }
    ) {
        Canvas(modifier = Modifier.fillMaxSize()) {
            // 更新屏幕中心
            screenCenter.value = Offset(size.width / 2f, size.height / 2f)

            connections.forEach { conn ->
                val isHighlighted = clickedPointId.value?.let {
                    conn.fromPointId == it || conn.toPointId == it
                } ?: false

                val lineColor = if (isHighlighted) Color.Blue else conn.color
                val lineWidth = if (isHighlighted) 4f else conn.strokeWidth

                val startPoint = points.first { it.id == conn.fromPointId }
                val endPoint = points.first { it.id == conn.toPointId }

                val startPos = pointPositionAnimations[startPoint.id]?.value ?: Offset(startPoint.baseX, startPoint.baseY)
                val endPos = pointPositionAnimations[endPoint.id]?.value ?: Offset(endPoint.baseX, endPoint.baseY)

                val start = (startPos + pointOffsets[conn.fromPointId]!!) * scale.value + offset.value
                val end = (endPos + pointOffsets[conn.toPointId]!!) * scale.value + offset.value

                drawLine(
                    color = lineColor,
                    start = start,
                    end = end,
                    strokeWidth = lineWidth * scale.value
                )
            }

            points.forEach { point ->
                val position = pointPositionAnimations[point.id]?.value ?: Offset(point.baseX, point.baseY)
                val center = (position + pointOffsets[point.id]!!) * scale.value + offset.value
                val depth = (cos(Math.toRadians(point3DAngles[point.id]!!.toDouble())) * 0.3 + 0.7).toFloat()
                var currentSize = dynamicSizes[point.id]!!

                // 应用动画缩放
                val scaleAnimation = pointScaleAnimations[point.id]?.value ?: 1f
                currentSize *= scaleAnimation

                drawCircle(
                    color = point.color.copy(alpha = 0.3f * depth),
                    radius = currentSize * 1.5f * scale.value,
                    center = center
                )

                drawCircle(
                    color = point.color.copy(alpha = depth),
                    radius = currentSize * scale.value,
                    center = center,
                    style = Stroke(width = 2f * depth * scale.value)
                )

                drawCircle(
                    color = point.color,
                    radius = currentSize * 0.6f * scale.value,
                    center = center
                )
            }
        }
    }
}

@Composable
fun NetworkAnimationToggleScreen() {
    // 管理是否显示 NetworkAnimationScreen 的状态
    var showAnimation by remember { mutableStateOf(false) }

    Column(modifier = Modifier.fillMaxSize()) {
        // 切换显示/隐藏的按钮
        Button(
            onClick = { showAnimation = !showAnimation },
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth()
        ) {
            Text(text = if (showAnimation) "关闭网络动画" else "显示网络动画")
        }

        // 根据状态决定是否显示动画页面
        if (showAnimation) {
            Box(modifier = Modifier.fillMaxSize()) {
                NetworkAnimationScreen()
            }
        }
    }
}